package com.example.basic.web.service.user.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.basic.base.impl.BaseEntityServiceImpl;
import com.example.basic.exception.ServiceException;
import com.example.basic.utils.*;
import com.example.basic.web.enums.DataCodeEnum;
import com.example.basic.web.enums.EnableTypeEnum;
import com.example.basic.web.enums.YesNoEnum;
import com.example.basic.web.mapper.user.UserMapper;
import com.example.basic.web.model.user.User;
import com.example.basic.web.service.dataCode.DataCodeService;
import com.example.basic.web.service.user.UserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import java.util.List;

import static com.example.basic.utils.CheckUtil.notNull;


@Service
public class UserServiceImpl extends BaseEntityServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private DataCodeService dataCodeService;

    @Resource
    private HttpServletRequest request;


    /**
     * 新增修改人员
     * @param user
     * @return
     */
    @Override
    public User addAndUpdate(User user) {
        //参数校验
        verifyParam(user);

        //生成拼音码五笔码
        generatePyWbCode(user);

        if (StringUtils.emptyParams(user.getUserCode())) {
            LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
            // 登录名唯一
            lqw.eq(User::getLoginName,user.getLoginName());
            lqw.eq(User::getDeleteFlag,YesNoEnum.NO_FLAG.getType());
            User loginNameInfo = userMapper.selectOne(lqw);
            if (loginNameInfo != null){
                throw new ServiceException("登录名已存在");
            }

            // 用户名唯一
            lqw = new LambdaQueryWrapper<>();
            lqw.eq(User::getUserName,user.getUserName());
            lqw.eq(User::getDeleteFlag,YesNoEnum.NO_FLAG.getType());
            User userNameInfo = userMapper.selectOne(lqw);
            if (userNameInfo != null){
                throw new ServiceException("用户已存在");
            }

            if(StringUtils.notEmptyParams(user.getIdNo())){
                //身份证号唯一
                lqw = new LambdaQueryWrapper<>();
                lqw.eq(User::getIdNo,user.getIdNo());
                lqw.eq(User::getDeleteFlag,YesNoEnum.NO_FLAG.getType());
                User idCardInfo = userMapper.selectOne(lqw);
                if(idCardInfo != null){
                    throw new ServiceException("身份证号已存在");
                }
            }

            // 如果没有设置密码或前段没有输入密码选项，则设置为默认的abcabc
            if(StringUtils.emptyParams(user.getLoginPwd())){
                user.setLoginPwd("123456");
            }
            // 设置用户密码（md5加密）
            user.setLoginPwd(DigestUtils.md5ToHex(user.getLoginPwd()));
            String userCode = dataCodeService.generateDataCodeNo(DataCodeEnum.USER_CODE.getType());
            user.setUserCode(userCode);
            if (StringUtils.emptyParams(user.getAge())){
                String birthdayStr = user.getIdNo().substring(6, 14);
                String age = GetAgeByBirth.getAgeFromBirthTime(birthdayStr);
                user.setAge(age);
            }
            preCreate(user);
            super.insert(user);
        }else {
            //编辑用户
            notNull(user.getId(),"用户id不能为空");
            notNull(user.getUserCode(),"用户编码不能为空");
            //判断身份证号是否重复
            LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
            if(StringUtils.notEmptyParams(user.getIdNo())){
                //身份证号唯一
                lqw = new LambdaQueryWrapper<>();
                lqw.eq(User::getIdNo,user.getIdNo());
                lqw.eq(User::getDeleteFlag,YesNoEnum.NO_FLAG.getType());
                lqw.ne(User::getUserCode,user.getUserCode());
                User idCardInfo = userMapper.selectOne(lqw);
                if(idCardInfo != null){
                    throw new ServiceException("身份证号已存在");
                }
            }
            //用户名唯一
            lqw = new LambdaQueryWrapper<>();
            lqw.eq(User::getUserName,user.getUserName());
            lqw.ne(User::getUserCode,user.getUserCode());
            lqw.eq(User::getDeleteFlag,YesNoEnum.NO_FLAG.getType());
            User userNameInfo = userMapper.selectOne(lqw);
            if (userNameInfo != null){
                throw new ServiceException("用户已存在");
            }
            preUpdate(user);
            userMapper.updateById(user);
        }

        return user;
    }

    /**
     * @create 生成五笔码、拼音码
     * @param user 模型实体类
     */
    private void generatePyWbCode(User user) {
        // 获取角色名
        String userName = StringUtils.safeToString(user.getUserName(), "");
        // 生成拼音码
        if("".equals(StringUtils.safeToString(user.getPyCode(),"").replaceAll(" ",""))) {
            String userNamePinyin = PinyinUtils.getSimplePinYin(userName);
            user.setPyCode(userNamePinyin);
        }
        // 生成拼音码
        if("".equals(StringUtils.safeToString(user.getWbCode(),"").replaceAll(" ",""))) {
            String userNameWubi = WubiUtils.getSimpleWuBi(userName);
            user.setWbCode(userNameWubi);
        }
    }

    /**
     * 用户详情
     * @param userCode 用户编码
     * @return
     */
    @Override
    public User detail(String userCode) {
        notNull(userCode,"用户编码不能为空");

        return this.mapper.detail(userCode);
    }

    /**
     * 停用启用
     * @param userCode 用户编码
     * @return
     */
    @Override
    public Boolean enabled(String userCode) {
        notNull(userCode,"用户编码不能为空");

        User user = this.detail(userCode);

        if(user == null ){
            throw new ServiceException("未获取到需要操作的用户信息");
        }

        //停用启用
        if(user.getEnableFlag().equals(EnableTypeEnum.ON.getType())){
            user.setEnableFlag(EnableTypeEnum.OFF.getType());
        }else {
            user.setEnableFlag(EnableTypeEnum.ON.getType());
        }

        if(this.updateById(user) > 0){
            return true;
        }

        throw new ServiceException("操作失败");
    }

    /**
     * 锁定解锁
     * @param userCode 用户编码
     * @return
     */
    @Override
    public Boolean lockUnlock(String userCode) {
        notNull(userCode,"用户编码不能为空");

        User user = this.detail(userCode);

        if(user == null ){
            throw new ServiceException("未获取到需要操作的用户信息");
        }

        //停用启用
        if(user.getLockFlag().equals(EnableTypeEnum.ON.getType())){
            user.setLockFlag(EnableTypeEnum.OFF.getType());
        }else {
            user.setLockFlag(EnableTypeEnum.ON.getType());
        }

        if(this.updateById(user) > 0){
            return true;
        }

        throw new ServiceException("操作失败");
    }

    /**
     * 删除
     * @param userCode 用户编码
     * @return
     */
    @Override
    public Boolean remove(String userCode) {
        notNull(userCode,"用户编码不能为空");

        User user = this.detail(userCode);
        if(user == null ){
            throw new ServiceException("未获取到需要删除的用户信息");
        }

        if(this.deleteById(user.getId()) > 0){
            return true;
        }

        throw new ServiceException("删除失败");
    }
    /**
     * 重置用户密码
     * @param loginName 需要重置的登录名
     * @param loginUserCode 操作人唯一代码
     * @return
     */

    @Override
    public Boolean resetPwd(String loginName, String loginUserCode) {
        // 验证此用户是否存在
        User loginSysUsers = this.detail(loginUserCode);
        if(loginSysUsers == null){
            throw new ServiceException("当前登录人信息不存在，请核实用户信息");
        }

        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        // 登录名唯一
        lqw.eq(User::getLoginName,loginName);
        lqw.eq(User::getDeleteFlag,YesNoEnum.NO_FLAG.getType());
        User loginNameInfo = userMapper.selectOne(lqw);
        if(loginNameInfo == null){
            throw new ServiceException("需要重置密码的用户信息不存在，请核实用户信息");
        }

        // 设置用户默认密码（md5加密）
        loginNameInfo.setLoginPwd(DigestUtils.md5ToHex("abcabc"));
        // 重置用户密码
        if(super.updateById(loginNameInfo) > 0){
            return true;
        }
        throw new ServiceException("重置失败");

    }

    /**
     * 用户列表
     * @param queryPage 分页
     * @param searchParam 用户名/登录名
     * @param status 状态，0-全部，1-启用，2-停用，3-锁定
     * @return
     */
    @Override
    public IPage<User> queryList(Page<User> queryPage, String searchParam, String status) {

        return userMapper.queryList(queryPage ,searchParam,status);
    }

    /**
     * 通过登录名查询用户信息
     * @param loginName 登录名
     * @return
     */
    @Override
    public User queryUserByLoginName(String loginName) {
        notNull(loginName,"登录名不能为空");

        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.eq(User::getLoginName,loginName);
        lqw.eq(User::getDeleteFlag,YesNoEnum.NO_FLAG.getType());
        return this.mapper.selectOne(lqw);
    }

    /**
     * 通过角色查询用户列表
     * @param roleCode 角色编码
     * @return
     */
    @Override
    public List<User> queryUserByRoleCode(String roleCode) {
        notNull(roleCode,"角色编码不能为空");

        return userMapper.queryUserByRoleCode(roleCode);
    }

    /**
     * 修改密码
     * @param loginName
     * @param oriPwd 加密后的原密码
     * @param newPwd 加密后的新密码
     * @return
     */
    @Override
    public Boolean modifyPwd(String loginName, String oriPwd, String newPwd) {
        notNull(loginName, "登录名不能为空");
        notNull(oriPwd, "原密码不能为空");
        notNull(newPwd, "新密码不能为空");

        //根据登录账号查询用户
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
        lqw.eq(User::getLoginName, loginName);
        User user = this.mapper.selectOne(lqw);

        if(user == null){
            throw new ServiceException("登录名无效");
        }

        //校验密码是否准确
        if (!oriPwd.equals(user.getLoginPwd())) {
            throw new ServiceException("原密码不正确");
        }
        //修改密码
        user.setLoginPwd(newPwd);
        this.updateById(user);

        return true;
    }

    /**
     * @Description
     * 校验系统用户参数
     * @date 2024/3/2 10:36
     * @author wjq
     * @param params 系统用户实体
     * @return
     */
    private void verifyParam(User params){
        notNull(params.getLoginName(),"用户登录名不能为空！");
        notNull(params.getUserName(),"用户名不能为空！");
        notNull(params.getUserClass(),"用户类型不能为空！");
//        notNull(params.getIdNo(),"身份证号不能为空！");
        notNull(params.getSexCode(),"性别不能为空！");
        notNull(params.getAge(),"年龄不能为空！");
        notNull(params.getBelongDept(),"所属部门不能为空！");
        notNull(params.getResponsibleDept(),"负责部门不能为空！");
        notNull(params.getRoleCode(),"用户角色不能为空");
        CheckIDCard.IdentityCardVerification(params.getIdNo());
    }
}
